package com.ttsx.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeCloseModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ttsx.core.common.constant.AlipayConstants;
import com.ttsx.core.common.enums.OrderStatusEnum;
import com.ttsx.core.common.enums.PayStatusEnum;
import com.ttsx.core.common.enums.PayTypeEnum;
import com.ttsx.core.common.enums.RefundStatus;
import com.ttsx.core.common.exception.TTSXException;
import com.ttsx.mapper.OrderMapper;
import com.ttsx.pojo.dto.order.OrderCreateDTO;
import com.ttsx.pojo.dto.order.OrderQueryDTO;
import com.ttsx.pojo.entity.*;
import com.ttsx.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * @author lucky
 * @description 针对表【ttsx_order(订单表)】的数据库操作Service实现
 * @createDate 2025-03-01 17:41:06
 */

@Slf4j
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order>
        implements OrderService {

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private CartService cartService;

    @Autowired
    private PaymentService paymentService;
    @Autowired
    private UserService userService;

    @Autowired
    private UserAddressService userAddressService;

    @Autowired
    private RefundService refundService;

    @Override
    public PageInfo<Order> getPage(Integer pIndex, Integer pSize, OrderQueryDTO orderQueryDTO) {
        PageHelper.startPage(pIndex, pSize);

        Long userId = orderQueryDTO.getUserId();
        Integer orderStatus = orderQueryDTO.getOrderStatus();
        Double priceStart = orderQueryDTO.getPriceStart();
        Double priceEnd = orderQueryDTO.getPriceEnd();
        String createTimeStart = orderQueryDTO.getCreateTimeStart();
        String createTimeEnd = orderQueryDTO.getCreateTimeEnd();

        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(ObjectUtil.isNotNull(userId), Order::getUserId, userId);
        lqw.eq(ObjectUtil.isNotNull(orderStatus), Order::getOrderStatus, orderStatus);
        lqw.ge(ObjectUtil.isNotNull(priceStart), Order::getTotalAmount, priceStart);
        lqw.le(ObjectUtil.isNotNull(priceEnd), Order::getTotalAmount, priceEnd);
        lqw.ge(StrUtil.isNotBlank(createTimeStart), Order::getCreateTime, createTimeStart);
        lqw.le(StrUtil.isNotBlank(createTimeEnd), Order::getCreateTime, createTimeEnd);

        lqw.orderByDesc(Order::getCreateTime);

        List<Order> orders = baseMapper.selectList(lqw);
        orders.forEach(order -> {
            order.setUser(userService.getById(order.getUserId()));
            order.setAddress(userAddressService.getById(order.getAddrId()));
            order.setOrderStatusDesc(OrderStatusEnum.getDesc(order.getOrderStatus()));
            order.setOrderItems(orderItemService.getListByOrderId(order.getId()));
        });

        return new PageInfo<>(orders, 5);
    }

    @Transactional
    @Override
    public String createOrder(OrderCreateDTO orderCreateDTO) {
        // 保存订单
        Order order = saveOrder(orderCreateDTO);

        // 获取购物车ID集合
        List<Long> cartIds = orderCreateDTO.getCartIds();

        // 保存订单详情
        saveOrderItem(order.getId(), cartIds);

        // 清空购物车
        cartService.removeBatchByIds(cartIds);

        // 创建支付链接
        AlipayTradePagePayResponse response = paymentService.createPay(order, orderCreateDTO.getPayMethod());
        log.info("创建支付请求结果：{}", JSONUtil.toJsonStr( response));
        if (response != null) {
            // 保存支付信息
            savePayment(order.getOrderNo(), response.getTradeNo(), orderCreateDTO);
            return response.getBody();
        }

        return null;
    }

    /**
     * 取消支付
     *
     * @param payMethod 支付方式
     * @param tradeNo   交易号
     * @param payNo     支付号
     * @return 是否取消成功
     */
    private boolean cancelPay(Integer payMethod, String tradeNo, String payNo) {
        if (ObjectUtil.equal(payMethod, PayTypeEnum.ALIPAY.getCode())) {
            // 创建支付宝客户端
            AlipayClient alipayClient = new DefaultAlipayClient(
                    AlipayConstants.GATEWAY_URL,
                    AlipayConstants.APP_ID,
                    AlipayConstants.PRIVATE_KEY,
                    "json",
                    AlipayConstants.CHARSET,
                    AlipayConstants.PUBLIC_KEY,
                    AlipayConstants.SIGN_TYPE
            );

            AlipayTradeCloseRequest closeRequest = new AlipayTradeCloseRequest();

            AlipayTradeCloseModel model = new AlipayTradeCloseModel();
            model.setTradeNo(tradeNo);
            model.setOutTradeNo(payNo);
            closeRequest.setBizModel(model);

            try {
                AlipayTradeCloseResponse execute = alipayClient.execute(closeRequest);
                log.info("支付请求关闭结果：{}", execute);
                return execute.isSuccess();
            } catch (AlipayApiException e) {
                throw new TTSXException("支付请求关闭失败");
            }
        }

        return false;
    }


    private boolean payRefund(String orderNo) {
        Payment payment = paymentService.getByOrderNo(orderNo);

        // 创建支付宝客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                AlipayConstants.GATEWAY_URL,
                AlipayConstants.APP_ID,
                AlipayConstants.PRIVATE_KEY,
                "json",
                AlipayConstants.CHARSET,
                AlipayConstants.PUBLIC_KEY,
                AlipayConstants.SIGN_TYPE
        );

        AlipayTradeRefundRequest refundRequest = new AlipayTradeRefundRequest();
        AlipayTradeRefundModel model = new AlipayTradeRefundModel();

        model.setOutTradeNo(payment.getPayNo());
        model.setTradeNo(payment.getTradeNo());
        model.setRefundAmount(payment.getAmount().toString());
        model.setRefundReason("用户取消订单");
        model.setOutRequestNo("TK" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss"));

        refundRequest.setBizModel(model);

        // 记录退款信息
        Refund refund = new Refund();
        refund.setRefundNo(model.getOutRequestNo());
        refund.setPayNo(payment.getPayNo());
        refund.setTradeNo(payment.getTradeNo());
        refund.setRefundAmount(payment.getAmount());
        refund.setRefundReason(model.getRefundReason());

        try {
            AlipayTradeRefundResponse response = alipayClient.execute(refundRequest);
            log.info("退款结果：{}", response);

            if (response.isSuccess()) {
                payment.setPayStatus(PayStatusEnum.REFUNDED.getCode());
                paymentService.updateById(payment);

                refund.setRefundStatus(RefundStatus.REFUNDED.getCode());
                refund.setRefundTime(LocalDateTime.now());
                refundService.save(refund);

                return true;
            } else {
                refund.setRefundStatus(RefundStatus.REFUND_FAILED.getCode());
                refundService.save(refund);
                return false;
            }


        } catch (AlipayApiException e) {
            refund.setRefundStatus(RefundStatus.REFUND_FAILED.getCode());
            refundService.save(refund);
            throw new TTSXException("退款失败");
        }


    }


    @Override
    public void orderCancel(Long orderId) {
        Order order = getById(orderId);
        Payment payment = paymentService.getByOrderNo(order.getOrderNo());
        boolean b;
        if (ObjectUtil.equal(payment.getPayStatus(), PayStatusEnum.PAID.getCode())) {
            b = payRefund(payment.getOrderNo());
        } else {
            b = cancelPay(payment.getPayMethod(), payment.getTradeNo(), payment.getPayNo());
        }

        // 更新订单状态
        if (b) {
            order.setId(orderId);
            order.setOrderStatus(OrderStatusEnum.CANCELED.getCode());
            baseMapper.updateById(order);
        }
    }

    @Override
    public boolean shipped(String orderNo) {
        Order order = getByOrderNo(orderNo);
        order.setOrderStatus(OrderStatusEnum.UNPAID.getCode());
        return baseMapper.updateById(order) > 0;
    }

    @Override
    public Order getByOrderNo(String orderNo) {
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getOrderNo, orderNo);
        return baseMapper.selectOne(lqw);
    }


    /**
     * 保存订单信息
     *
     * @param orderCreateDTO 订单创建信息
     * @return 订单信息
     */
    private Order saveOrder(OrderCreateDTO orderCreateDTO) {
        Order order = new Order();
        order.setOrderNo("DD" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss"));
        order.setUserId(orderCreateDTO.getUserId());
        order.setTotalAmount(orderCreateDTO.getTotalAmount());
        order.setAddrId(orderCreateDTO.getAddrId());
        order.setPostage(orderCreateDTO.getPostage());
        order.setPayMethod(orderCreateDTO.getPayMethod());
        order.setOrderStatus(OrderStatusEnum.UNPAID.getCode());

        baseMapper.insert(order);

        return order;
    }

    /**
     * 保存支付信息
     *
     * @param orderNo        订单编号
     * @param tradeNO        交易号
     * @param orderCreateDTO 订单创建信息
     */
    private void savePayment(String orderNo, String tradeNO, OrderCreateDTO orderCreateDTO) {
        Payment payment = new Payment();
        payment.setPayNo("ZF" + LocalDateTimeUtil.format(LocalDateTime.now(), "yyyyMMddHHmmss"));
        payment.setOrderNo(orderNo);
        payment.setTradeNo(tradeNO);
        payment.setAmount(orderCreateDTO.getTotalAmount());
        payment.setPayStatus(PayStatusEnum.UNPAID.getCode());
        payment.setPayMethod(orderCreateDTO.getPayMethod());
        paymentService.save(payment);
    }

    /**
     * 保存订单详情
     *
     * @param orderId 订单ID
     * @param cartIds 购物车ID集合
     */
    private void saveOrderItem(Long orderId, List<Long> cartIds) {
        cartIds.forEach(cartId -> {
            OrderItem orderItem = new OrderItem();
            orderItem.setOrderId(orderId);
            Cart cart = cartService.getByCartId(cartId);
            orderItem.setProductId(cart.getProductId());
            orderItem.setQuantity(cart.getQuantity());
            orderItem.setPrice(cart.getProduct().getPrice());
            orderItemService.save(orderItem);
        });
    }
}




